home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 359_11 / patch5.000 / GO32 / PAGING.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-11  |  16.7 KB  |  692 lines

  1. /* This is file PAGING.C */
  2. /*
  3. ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. /* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
  16. /* History:112,12 */
  17.  
  18. #include <dos.h>
  19. #include <fcntl.h>
  20. #include <io.h>
  21. #include <sys/stat.h>
  22.  
  23. #include "build.h"
  24. #include "types.h"
  25. #include "paging.h"
  26. #include "graphics.h"
  27. #include "tss.h"
  28. #include "idt.h"
  29. #include "gdt.h"
  30. #include "valloc.h"
  31. #include "dalloc.h"
  32. #include "utils.h"
  33. #include "aout.h"
  34. #include "mono.h"
  35. #include "vcpi.h"
  36.  
  37. #define VERBOSE 0
  38.  
  39. #if DEBUGGER
  40. #define MAX_PAGING_NUM 1
  41. #else
  42. #define MAX_PAGING_NUM 4
  43. #endif
  44.  
  45. extern word32 ptr2linear(void far *ptr);
  46.  
  47. CLIENT    client;        /*  VCPI Change Mode Structure  */
  48. word32    abs_client;    /*  _DS * 16L + &client        */
  49. far32    vcpi_entry;
  50. SYS_TBL    int_descriptor;
  51. SYS_TBL gbl_descriptor;
  52.  
  53. extern word16 vcpi_installed;    /*  VCPI Installed Flag  */
  54. extern near protect_entry();
  55.  
  56. extern TSS *utils_tss;
  57. extern int debug_mode;
  58. extern word16 mem_avail;
  59. extern int self_contained;
  60. extern long header_offset;
  61.  
  62. typedef struct AREAS {
  63.   word32 first_addr;
  64.   word32 last_addr;
  65.   word32 foffset; /* corresponding to first_addr; -1 = zero fill only */
  66.   } AREAS;
  67.  
  68. #define MAX_AREA    8
  69. static AREAS areas[MAX_AREA];
  70. static char *aname[MAX_AREA] = {
  71.     "text ",
  72.     "data ",
  73.     "bss  ",
  74.     "arena",
  75.     "stack",
  76.     "vga  ",
  77.     "syms ",
  78.     "emu"
  79. };
  80. static char achar[MAX_AREA] = "tdbmsg?e";
  81. typedef enum {
  82.   A_text,
  83.   A_data,
  84.   A_bss,
  85.   A_arena,
  86.   A_stack,
  87.   A_vga,
  88.   A_syms,
  89.   A_emu
  90. } AREA_TYPES;
  91.  
  92. static aout_f;
  93. static emu_f;
  94.  
  95. word32 far *pd = 0;
  96. word32 far *graphics_pt;
  97. extern word32 graphics_pt_lin;
  98. char paging_buffer[4096*MAX_PAGING_NUM];
  99.  
  100. /*  VCPI Get Interface  */
  101. void    link_vcpi(word32 far *dir, word32 far *table)
  102. {
  103.  
  104.   vcpi_entry.selector = g_vcpicode * 8;
  105.   vcpi_entry.offset32 = get_interface(table,&gdt[g_vcpicode]);
  106.   if (vcpi_entry.offset32 == -1L)
  107.     {
  108.     printf("CAUTION !!!!  This EMS driver used address 1B0000H.\n");
  109.     printf("This memory area is broken by handle_screen_swap().\n");
  110.     exit(1);
  111.     }
  112.  
  113.   int_descriptor.limit_16 = sizeof(idt);
  114.   int_descriptor.base_32  = ptr2linear(idt);
  115.   gbl_descriptor.limit_16 = sizeof(gdt);
  116.   gbl_descriptor.base_32  = ptr2linear(gdt);
  117.  
  118.   client.page_table   = (word32)dir>>12;
  119.   client.gdt_address  = ptr2linear(&gbl_descriptor);
  120.   client.idt_address  = ptr2linear(&int_descriptor);
  121.   client.ldt_selector = 0;
  122.   client.tss_selector = g_ctss * 8;
  123.   client.entry_eip    = (word16)protect_entry;
  124.   client.entry_cs     = g_rcode * 8;
  125.  
  126.   abs_client = ptr2linear(&client);
  127. }
  128.  
  129. handle_screen_swap(word32 far *pt)
  130. {
  131.   struct REGPACK r;
  132.   int have_mono=0;
  133.   int have_color=0;
  134.   int have_graphics=0;
  135.   int save, new, i;
  136.  
  137.   r.r_ax = 0x1200;
  138.   r.r_bx = 0xff10;
  139.   r.r_cx = 0xffff;
  140.   intr(0x10, &r);
  141.   if (r.r_cx == 0xffff)
  142.     pokeb(0x40, 0x84, 24); /* the only size for CGA/MDA */
  143.  
  144.   save = peekb(screen_seg, 0);
  145.   pokeb(screen_seg, 0, ~save);
  146.   new = peekb(screen_seg, 0);
  147.   pokeb(screen_seg, 0, save);
  148.   if (new == ~save)
  149.     have_color = 1;
  150.  
  151.   save = peekb(0xb000, 0);
  152.   pokeb(0xb000, 0, ~save);
  153.   new = peekb(0xb000, 0);
  154.   pokeb(0xb000, 0, save);
  155.   if (new == ~save)
  156.     have_mono = 1;
  157.  
  158.   r.r_ax = 0x0f00;
  159.   intr(0x10, &r);
  160.   if ((r.r_ax & 0xff) > 0x07)
  161.     have_graphics = 1;
  162.  
  163.   if (have_graphics && have_mono)
  164.     have_color = 1;
  165.   else if (have_graphics && have_color)
  166.     have_mono = 1;
  167.  
  168.   for (i=0; i<16; i++)
  169.     pt[0x1b0+i] = pt[0xb0+i];
  170.  
  171.   if (have_color && !have_mono)
  172.   {
  173.     for (i=0; i<8; i++)
  174.       pt[0x1b0+i] = pt[0xb8+i];
  175.     return;
  176.   }
  177.   if (have_mono & !have_color)
  178.   {
  179.     for (i=0; i<8; i++)
  180.       pt[0x1b8+i] = pt[0xb0+i];
  181.     return;
  182.   }
  183.  
  184.   if ((biosequip() & 0x0030) == 0x0030) /* mono mode, swap! */
  185.   {
  186.     for (i=0; i<8; i++)
  187.     {
  188.       pt[0x1b0+i] ^= pt[0x1b8+i];
  189.       pt[0x1b8+i] ^= pt[0x1b0+i];
  190.       pt[0x1b0+i] ^= pt[0x1b8+i];
  191.     }
  192.     return;
  193.   }
  194. }
  195.  
  196. paging_set_file(char *fname)
  197. {
  198.   word32 far *pt;
  199.   FILEHDR filehdr;
  200.   AOUTHDR aouthdr;
  201.   SCNHDR scnhdr[3];
  202.   GNU_AOUT gnu_aout;
  203.   int i;
  204.   aout_f = open(fname, O_RDONLY|O_BINARY);
  205.   if (aout_f < 0)
  206.   {
  207.     printf("Can't open file <%s>\n", fname);
  208.     exit(1);
  209.   }
  210.  
  211. #if TOPLINEINFO
  212.   for (i=0; fname[i]; i++)
  213.     poke(screen_seg, i*2+10, fname[i] | 0x0700);
  214. #endif
  215.  
  216.   lseek(aout_f, header_offset, 0);
  217.  
  218.   read(aout_f, &filehdr, sizeof(filehdr));
  219.   if (filehdr.f_magic != 0x14c)
  220.   {
  221.     lseek(aout_f, header_offset, 0);
  222.     read(aout_f, &gnu_aout, sizeof(gnu_aout));
  223.     a_tss.tss_eip = gnu_aout.entry;
  224.     aouthdr.tsize = gnu_aout.tsize;
  225.     aouthdr.dsize = gnu_aout.dsize;
  226.     aouthdr.bsize = gnu_aout.bsize;
  227.   }
  228.   else
  229.   {
  230.     read(aout_f, &aouthdr, sizeof(aouthdr));
  231.     a_tss.tss_eip = aouthdr.entry;
  232.     read(aout_f, scnhdr, sizeof(scnhdr));
  233.   }
  234.   a_tss.tss_cs = g_acode*8;
  235.   a_tss.tss_ds = g_adata*8;
  236.   a_tss.tss_es = g_adata*8;
  237.   a_tss.tss_fs = g_adata*8;
  238.   a_tss.tss_gs = g_adata*8;
  239.   a_tss.tss_ss = g_adata*8;
  240.   a_tss.tss_esp = 0x7ffffffc;
  241.  
  242.   if (filehdr.f_magic == 0x14c)
  243.   {
  244.     areas[0].first_addr = aouthdr.text_start + ARENA;
  245.     areas[0].foffset = scnhdr[0].s_scnptr + header_offset;
  246.     areas[0].last_addr = areas[0].first_addr + aouthdr.tsize;
  247.   }
  248.   else if (filehdr.f_magic == 0x10b)
  249.   {
  250.     areas[0].first_addr = ARENA;
  251.     if (a_tss.tss_eip >= 0x1000)    /* leave space for null reference */
  252.       areas[0].first_addr += 0x1000;    /* to cause seg fault */
  253.     areas[0].foffset = header_offset;
  254.     areas[0].last_addr = areas[0].first_addr + aouthdr.tsize + 0x20;
  255.   }
  256. #if DEBUGGER
  257.   else if (filehdr.f_magic == 0x107)
  258.   {
  259.     struct stat sbuf;
  260.     fstat(aout_f, &sbuf);
  261.     areas[0].first_addr = ARENA;
  262.     areas[0].foffset = 0x20 + header_offset;
  263.     areas[0].last_addr = sbuf.st_size + ARENA - 0x20;
  264.   }
  265.   else
  266.   {
  267.     struct stat sbuf;
  268.     fstat(aout_f, &sbuf);
  269.     areas[0].first_addr = ARENA;
  270.     areas[0].foffset = header_offset;
  271.     areas[0].last_addr = sbuf.st_size + ARENA;
  272.   }
  273. #else
  274.   else
  275.   {
  276.     printf("Unknown file type 0x%x (0%o)\n", filehdr.f_magic, filehdr.f_magic);
  277.     exit(-1);
  278.   }
  279. #endif
  280. #if DEBUGGER
  281.   if (debug_mode)
  282.     printf("%ld+", aouthdr.tsize);
  283. #endif
  284.  
  285.   if (filehdr.f_magic == 0x14c)
  286.   {
  287.     areas[1].first_addr = aouthdr.data_start + ARENA;
  288.     areas[1].foffset = scnhdr[1].s_scnptr + header_offset;
  289.   }
  290.   else
  291.   {
  292.     areas[1].first_addr = (areas[0].last_addr+0x3fffffL)&~0x3fffffL;
  293.     areas[1].foffset = ((aouthdr.tsize + 0x20 + 0xfffL) & ~0xfffL) + header_offset;
  294.   }
  295.   areas[1].last_addr = areas[1].first_addr + aouthdr.dsize - 1;
  296. #if DEBUGGER
  297.   if (debug_mode)
  298.     printf("%ld+", aouthdr.dsize);
  299. #endif
  300.  
  301.   areas[2].first_addr = areas[1].last_addr + 1;
  302.   areas[2].foffset = -1;
  303.   areas[2].last_addr = areas[2].first_addr + aouthdr.bsize - 1;
  304. #if DEBUGGER
  305.   if (debug_mode)
  306.     printf("%ld = %ld\n", aouthdr.bsize,
  307.       aouthdr.tsize+aouthdr.dsize+aouthdr.bsize);
  308. #endif
  309.  
  310.   areas[3].first_addr = areas[2].last_addr;
  311.   areas[3].last_addr = areas[3].first_addr;
  312.   areas[3].foffset = -1;
  313.  
  314.   areas[4].first_addr = 0x50000000;
  315.   areas[4].last_addr = 0x8fffffff;
  316.   areas[4].foffset = -1;
  317.  
  318.   areas[5].first_addr = 0xe0000000;
  319.   areas[5].last_addr = 0xe03fffff;
  320.   areas[5].foffset = -1;
  321.  
  322.   areas[A_syms].first_addr = 0xa0000000;
  323.   areas[A_syms].last_addr = 0xafffffff;
  324.   areas[A_syms].foffset = -1;
  325.  
  326.   pd = (word32 far *)((long)valloc(VA_640) << 24);
  327.   pt = (word32 far *)((long)valloc(VA_640) << 24);
  328.   for (i=0; i<1024; i++)
  329.     pd[i] = 0;
  330.  
  331.   if (vcpi_installed)
  332.     {
  333.     link_vcpi(pd,pt);        /*  Get VCPI Page Table  */
  334.     for ( i=0; i<1024; i++)
  335.       if (pt[i] & PT_P)
  336.     pt[i] |= PT_I;
  337.     }
  338.   else
  339.     {
  340.     for (i=0; i<256; i++)
  341.       pt[i] = ((unsigned long)i<<12) | PT_P | PT_W | PT_I;
  342.     for (; i<1024; i++)
  343.       pt[i] = 0;
  344.     }
  345.  
  346.   pd[0] = ((word32)pt >> 12) | PT_P | PT_W | PT_I;    /* map 0-1M 1:1 */
  347.   pd[0x3c0] = ((word32)pt >> 12) | PT_P | PT_W | PT_I;    /* map also to 0xF0000000 */
  348.   handle_screen_swap(pt);
  349.  
  350.   graphics_pt = (word32 far *)((long)valloc(VA_640) << 24);
  351.   graphics_pt_lin = ptr2linear(graphics_pt);
  352.   for (i=0; i<1024; i++)
  353.     graphics_pt[i] = 0x000a0000L | ((i * 4096L) & 0xffffL) | PT_W | PT_U;
  354.   pd[0x380] = ((word32)graphics_pt >> 12) | PT_P | PT_W | PT_U;
  355.  
  356.   c_tss.tss_cr3 = (unsigned long)pd >> 12;
  357.   a_tss.tss_cr3 = (unsigned long)pd >> 12;
  358.   o_tss.tss_cr3 = (unsigned long)pd >> 12;
  359.   i_tss.tss_cr3 = (unsigned long)pd >> 12;
  360.   p_tss.tss_cr3 = (unsigned long)pd >> 12;
  361.   f_tss.tss_cr3 = (unsigned long)pd >> 12;
  362.  
  363. #if VERBOSE
  364.     for (i=0; i<5; i++)
  365.       printf("%d %-10s %08lx-%08lx (offset 0x%08lx)\n", i, aname[i], areas[i].first_addr, areas[i].last_addr, areas[i].foffset);
  366. #endif
  367. }
  368.  
  369. #if TOPLINEINFO
  370. static update_status(int c, int col)
  371. {
  372.   int r;
  373.   r = peek(screen_seg, 2*79);
  374.   poke(screen_seg, 2*col, c);
  375.   return r;
  376. }
  377. #endif
  378.  
  379. word32 paging_brk(word32 b)
  380. {
  381.   word32 r = (areas[3].last_addr - ARENA + 7) & ~7;
  382.   areas[3].last_addr = b + ARENA;
  383.   return r;
  384. }
  385.  
  386. word32 paging_sbrk(int32 b)
  387. {
  388.   word32 r = (areas[3].last_addr - ARENA + 7) & ~7;
  389.   areas[3].last_addr = r + b + ARENA;
  390.   return r;
  391. }
  392.  
  393. page_is_valid(word32 vaddr)
  394. {
  395.   int a;
  396.   for (a=0; a<MAX_AREA; a++)
  397.     if ((vaddr <= areas[a].last_addr) && (vaddr >= areas[a].first_addr))
  398.       return 1;
  399.   if (vaddr >= 0xf000000L)
  400.     return 1;
  401.   return 0;
  402. }
  403.  
  404. page_in()
  405. {
  406.   int old_status;
  407.   TSS *old_util_tss;
  408.   word32 far *pt;
  409.   word32 far *p;
  410.   word32 vaddr, foffset, cnt32;
  411.   word32 eaddr, vtran, vcnt, zaddr;
  412.   int pdi, pti, pn, a, cnt, count;
  413.   unsigned dblock;
  414.  
  415. #if 0
  416.   unsigned char buf[100];
  417.   sprintf(buf, "0x%08lx", a_tss.tss_cr2 - ARENA);
  418.   for (a=0; buf[a]; a++)
  419.     poke(screen_seg, 80+a*2, 0x0600 | buf[a]);
  420. #endif
  421.  
  422.   old_util_tss = utils_tss;
  423.   utils_tss = &f_tss;
  424.   vaddr = tss_ptr->tss_cr2;
  425.  
  426.   for (a=0; a<MAX_AREA; a++)
  427.     if ((vaddr <= areas[a].last_addr) && (vaddr >= areas[a].first_addr))
  428.       goto got_area;
  429.  
  430.   printf("Segmentation Violation referencing address %#lx\n",
  431.          tss_ptr->tss_cr2-ARENA);
  432. #if !DEBUGGER
  433. /*  exit(1); */
  434. #endif
  435.   return 1;
  436.  
  437. got_area:
  438.   vaddr &= 0xFFFFF000;    /* points to beginning of page */
  439. #if 0 /* handled in protected mode for speed */
  440.   if (a == A_vga)
  441.     return graphics_fault(vaddr, graphics_pt);
  442. #endif
  443.  
  444. #if VERBOSE
  445.     printf("area(%d) - ", a);
  446. #endif
  447.  
  448.   if ((a == 2) & (vaddr < areas[a].first_addr)) /* bss, but data too */
  449.   {
  450. #if VERBOSE
  451.       printf("split page (data/bss) detected - ");
  452. #endif
  453.     a = 1; /* set to page in data */
  454.   }
  455.  
  456. #if TOPLINEINFO
  457.   old_status = update_status(achar[a] | 0x0a00, 78);
  458. #endif
  459. #if VERBOSE
  460.   printf("Paging in %s block for vaddr %#010lx -", aname[a], tss_ptr->tss_cr2-ARENA);
  461. #endif
  462.   pdi = (vaddr >> 22) & 0x3ff;
  463.   if (!(pd[pdi] & PT_P))    /* put in an empty page table if required */
  464.   {
  465.     pn = valloc(VA_640);
  466.     pt = (word32 far *)((word32)pn << 24);
  467.     pd[pdi] = ((word32)pn<<12) | PT_P | PT_W | PT_I | PT_S;
  468.     for (pti=0; pti<1024; pti++)
  469.       pt[pti] = PT_W | PT_S;
  470.   }
  471.   else
  472.     pt = (word32 far *)((pd[pdi]&~0xFFF) << 12);
  473.   pti = (vaddr >> 12) & 0x3ff;
  474.   if (pt[pti] & PT_P)
  475.   {
  476.     utils_tss = old_util_tss;
  477. #if TOPLINEINFO
  478.     update_status(old_status, 78);
  479. #endif
  480.     return 0;
  481.   }
  482.   count = MAX_PAGING_NUM;
  483.   if (count > mem_avail/4)
  484.     count = mem_avail/4;
  485.   if (pti + count > 1024)
  486.     count = 1024 - pti;
  487.   if (vaddr + count*4096L > areas[a].last_addr+4096L)
  488.     count = (areas[a].last_addr - vaddr + 4095) / 4096;
  489.   if (count < 1)
  490.     count = 1;
  491.   zaddr = eaddr = -1;
  492.   vtran = vaddr;
  493.   vcnt = 0;
  494.   for (; count; count--, pti++, vaddr+=4096)
  495.   {
  496.     if (pt[pti] & PT_P)
  497.       break;
  498.     dblock = pt[pti] >> 12;
  499.     pn = valloc(VA_1M);
  500.     pt[pti] &= 0xfffL & ~(word32)(PT_A | PT_D | PT_C);
  501.     pt[pti] |= ((word32)pn << 12) | PT_P;
  502.  
  503.     if (pt[pti] & PT_I)
  504.     {
  505. #if VERBOSE
  506.         printf(" swap");
  507. #endif
  508.       dread(paging_buffer, dblock);
  509.       dfree(dblock);
  510.       memput(vaddr, paging_buffer, 4096);
  511.     }
  512.     else
  513.     {
  514.       if (areas[a].foffset != -1)
  515.       {
  516. #if VERBOSE
  517.         if (a == A_emu)
  518.           printf(" emu");
  519.         else
  520.           printf(" exec");
  521. #endif
  522.         if (eaddr == -1)
  523.         {
  524.           eaddr = areas[a].foffset + (vaddr - areas[a].first_addr);
  525.           vtran = vaddr;
  526.         }
  527.         cnt32 = areas[a].last_addr - vaddr + 1;
  528.         if (cnt32 > 4096)
  529.           cnt32 = 4096;
  530.         else
  531.           zaddr = vaddr;
  532.         vcnt += cnt32;
  533.       }
  534.       else
  535.       {
  536.         zero32(vaddr);
  537. #if VERBOSE
  538.         printf(" zero");
  539. #endif
  540.       }
  541.       pt[pti] |= PT_I;
  542.     }
  543.   }
  544.   if (eaddr != -1)
  545.   {
  546.     int cur_f, rsize;
  547.     if (a == A_emu)
  548.       cur_f = emu_f;
  549.     else
  550.       cur_f = aout_f;
  551.     lseek(cur_f, eaddr, 0);
  552.     rsize = read(cur_f, paging_buffer, vcnt);
  553.     if (rsize < vcnt)
  554.       memset(paging_buffer+rsize, 0, vcnt-rsize);
  555.     if (zaddr != -1)
  556.       zero32(zaddr);
  557.     memput(vtran, paging_buffer, vcnt);
  558.   }
  559. #if VERBOSE
  560.   printf("\n");
  561. #endif
  562.   utils_tss = old_util_tss;
  563. #if TOPLINEINFO
  564.   update_status(old_status, 78);
  565. #endif
  566.   return 0;
  567. }
  568.  
  569. static last_po_pdi = 0;
  570. static last_po_pti = 0;
  571.  
  572. int page_out() /* return 1 if paged out, 0 if not */
  573. {
  574.   int start_pdi, start_pti, old_status;
  575.   word32 far *pt, v;
  576.   unsigned dblock, pn;
  577. #if TOPLINEINFO
  578.   old_status = update_status('>' | 0x0a00, 79);
  579. #endif
  580.   start_pdi = last_po_pdi;
  581.   start_pti = last_po_pti;
  582.   pt = (word32 far *)((pd[last_po_pdi]&~0xFFF) << 12);
  583.   do {
  584.     if ((pd[last_po_pdi] & (PT_P | PT_S)) == (PT_P | PT_S))
  585.     {
  586.       if ((pt[last_po_pti] & (PT_P | PT_S)) == (PT_P | PT_S))
  587.       {
  588.         pn = pt[last_po_pti] >> 12;
  589.         dblock = dalloc();
  590.         v = ((word32)last_po_pdi << 22) | ((word32)last_po_pti << 12);
  591.         memget(v, paging_buffer, 4096);
  592.         dwrite(paging_buffer, dblock);
  593.         pt[last_po_pti] &= 0xfff & ~PT_P; /* no longer present */
  594.         pt[last_po_pti] |= (long)dblock << 12;
  595.         vfree(pn);
  596. #if TOPLINEINFO
  597.         update_status(old_status, 79);
  598. #endif
  599.         return 1;
  600.       }
  601.     }
  602.     else /* imagine we just checked the last entry */
  603.       last_po_pti = 1023;
  604.     if (++last_po_pti == 1024)
  605.     {
  606.       last_po_pti = 0;
  607.       if (++last_po_pdi == 1024)
  608.         last_po_pdi = 0;
  609.       pt = (word32 far *)((pd[last_po_pdi]&~0xFFF) << 12);
  610.     }
  611.   } while ((start_pdi != last_po_pdi) || (start_pti != last_po_pti));
  612. #if TOPLINEINFO
  613.   update_status(old_status, 79);
  614. #endif
  615.   return 0;
  616. }
  617.  
  618. unsigned pd_dblock;
  619.  
  620. page_out_everything()
  621. {
  622.   int pdi;
  623.   unsigned ptb;
  624.   void far *fp;
  625.   while (page_out());
  626.   for (pdi=0; pdi<1024; pdi++)
  627.     if (pd[pdi])
  628.     {
  629.       ptb = dalloc();
  630.       fp = (void far *)((pd[pdi]&~0xFFF)<<12);
  631.       movedata(FP_SEG(fp), FP_OFF(fp), _DS, paging_buffer, 4096);
  632.       dwrite(paging_buffer, ptb);
  633.       vfree(pd[pdi]>>12);
  634.       pd[pdi] = (pd[pdi] & (0xFFF&~PT_P)) | ((word32)ptb<<12);
  635.     }
  636.   movedata(FP_SEG(pd), FP_OFF(pd), _DS, paging_buffer, 4096);
  637.   pd_dblock = dalloc();
  638.   dwrite(paging_buffer, pd_dblock);
  639.   vfree(((word32)pd)>>24);
  640.   xms_free();
  641. }
  642.  
  643. extern int valloc_initted;
  644.  
  645. page_in_everything()
  646. {
  647.   int pdi;
  648.   unsigned ptb;
  649.   word32 far *pt;
  650.   unsigned pta;
  651.   valloc_initted = 0;
  652.   pta = valloc(VA_640);
  653.   pd = (word32 far *)((word32)pta << 24);
  654.   dread(paging_buffer, pd_dblock);
  655.   dfree(pd_dblock);
  656.   movedata(_DS, paging_buffer, FP_SEG(pd), FP_OFF(pd), 4096);
  657.   for (pdi=0; pdi<1024; pdi++)
  658.     if (pd[pdi])
  659.     {
  660.       pta = valloc(VA_640);
  661.       pt = (word32 far *)((word32)pta << 24);
  662.       ptb = pd[pdi] >> 12;
  663.       dread(paging_buffer, ptb);
  664.       dfree(ptb);
  665.       movedata(_DS, paging_buffer, FP_SEG(pt), FP_OFF(pt), 4096);
  666.       pd[pdi] = (pd[pdi] & 0xFFF) | ((word32)pta<<12) | PT_P;
  667.     }
  668.   graphics_pt = (word32 far *)((pd[0x380]&~0xfff) << 12);
  669.   graphics_pt_lin = ptr2linear(graphics_pt);
  670. }
  671.  
  672.  
  673. int emu_install(char *filename)
  674. {
  675.   GNU_AOUT eh;
  676.   areas[A_emu].first_addr = EMU_TEXT+ARENA;
  677.   areas[A_emu].last_addr = EMU_TEXT-1+ARENA;
  678.   areas[A_emu].foffset = 0;
  679.  
  680.   if (filename == 0)
  681.     return 0;
  682.   emu_f = open(filename, O_RDONLY|O_BINARY);
  683.   if (emu_f < 0)
  684.   {
  685.     printf("Can't open 80387 emulator file <%s>\n", filename);
  686.     return 0;
  687.   }
  688.   read(emu_f, &eh, sizeof(eh));
  689.   areas[A_emu].last_addr += eh.tsize + eh.dsize + eh.bsize + 0x20;
  690.   return 1;
  691. }
  692.